﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

using ApocDev.TownsApi;
using ApocDev.TownsApi.XmlFiles;

using TownsModder.Controls;

using Action = ApocDev.TownsApi.XmlFiles.Action;

namespace TownsModder
{
    /// <summary>
    /// Interaction logic for ActionsWindow.xaml
    /// </summary>
    public partial class ActionsWindow : Window
    {
        public ActionsWindow()
        {
            InitializeComponent();

            if (!DesignerProperties.GetIsInDesignMode(new DependencyObject()))
            {
                lstItemsSelected.Visibility = Visibility.Collapsed;
                btnSelectItems.Visibility = Visibility.Collapsed;
                chkUseSource.Visibility = Visibility.Collapsed;
                txtActionQueueValue.Visibility = Visibility.Collapsed;
            }

            foreach (var priority in ModFiles.Priorities)
            {
                cbPriority.Items.Add(priority);
            }

            foreach (var action in ModFiles.Actions)
            {
                if (action == null)
                    continue;

                ListViewItem lvi = new ListViewItem();
                lvi.Content = action.ID;
                lvi.Tag = action;

                if (!string.IsNullOrEmpty(action.Name))
                    lvi.Content = action.ID + " (" + action.Name + ")";

                lstActions.Items.Add(lvi);
            }
            
            // Clean out any input info.
            ClearSelectedActionInfo();

            gbQueuedAction.Visibility = Visibility.Collapsed;
        }

        private void lstActions_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListViewItem selected = lstActions.SelectedItem as ListViewItem;

            if (selected == null)
            {
                ClearSelectedActionInfo();
                return;
            }

            var action = selected.Tag as Action;

            if (action == null)
            {
                ClearSelectedActionInfo();
                return;
            }

            SetSelectedActionInfo(action);
        }

        private void ClearSelectedActionInfo()
        {
            txtId.Text = null;
            txtName.Text = null;
            cbPriority.SelectedItem = null;
            txtActionQueueValue.Text = null;
            tvQueue.Items.Clear();

            txtActionQueueValue.IsEnabled = txtId.IsEnabled = txtName.IsEnabled = cbPriority.IsEnabled = tvQueue.IsEnabled = false;
        }

        private void SetSelectedActionInfo(Action action)
        {
            txtId.Text = action.ID;
            txtName.Text = action.Name;
            cbPriority.SelectedItem = action.Priority;
            CreateQueueTree(action);

            txtActionQueueValue.IsEnabled = txtId.IsEnabled = txtName.IsEnabled = cbPriority.IsEnabled = tvQueue.IsEnabled = true;

            //pgAction.SelectedObject = action;
        }

        private void CreateQueueTree(Action action)
        {
            tvQueue.Items.Clear();
            foreach (var qitem in action.Queue)
            {
                if (qitem == null)
                    continue;

                TreeViewWithIcons tvi = new TreeViewWithIcons();
                tvi.HeaderText = qitem.ToString();
                tvi.Icon = GetImageForActionQueueType(qitem);
                tvi.Tag = qitem;
                tvQueue.Items.Add(tvi);
            }
        }
        public BitmapImage CreateImage(string path)
        {
            // Little hack to pull an image for WPF. :)
            // Probably won't work if this assembly is ever obfuscated.
            return
                new BitmapImage(
                    new Uri(
                        string.Format(@"pack://application:,,,/{0};component/Images/Icons/{1}", Assembly.GetExecutingAssembly().GetName().Name, path),
                        UriKind.Absolute));
        }
        private ImageSource GetImageForActionQueueType(ActionQueueItem aqi)
        {
            if (aqi.Type == ActionQueueType.Unknown)
                return CreateImage("Error.png");
            return CreateImage("Apply.png");
        }

        private void HandleContextMenuRemove(object sender, RoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void HandleContextMenuInsertAbove(object sender, RoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void HandleContextMenuInsertBelow(object sender, RoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void HandleContextMenuMoveDown(object sender, RoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void HandleContextMenuMoveUp(object sender, RoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void tvQueue_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            var tvi = tvQueue.SelectedItem as TreeViewItem;
            if (tvi == null)
                return;

            var aqi = tvi.Tag as ActionQueueItem;
            if (aqi == null)
                return;

            chkUseSource.Visibility = Visibility.Visible;
            chkUseSource.IsEnabled = true;
            txtActionQueueValue.IsEnabled = true;
            txtActionQueueValue.Text = aqi.Value;
            chkUseSource.IsChecked = aqi.UseSource;

            SetupOptionsPane(aqi);
        }

        private int _maxQueueItemSelections = int.MaxValue;
        private IEnumerable<object> _queuedActionItemSource;
        private IEnumerable<object> _allItemsSource;
        private void SetupOptionsPane(ActionQueueItem item)
        {
            // Set this for some databinding.
            gbQueuedAction.DataContext = item;

            // Hide all the options first.
            lstItemsSelected.Visibility = Visibility.Collapsed;
            btnSelectItems.Visibility = Visibility.Collapsed;
            chkUseSource.Visibility = Visibility.Collapsed;
            txtActionQueueValue.Visibility = Visibility.Collapsed;
            _maxQueueItemSelections = int.MaxValue;

            switch (item.Type)
            {
                case ActionQueueType.PickFriendly:
                case ActionQueueType.Move:
                    chkUseSource.Visibility = Visibility.Visible;
                    // Hack for a fallthrough to the rest.
                    goto case ActionQueueType.ChangeTerrain;

                case ActionQueueType.ChangeTerrain:
                case ActionQueueType.CreateFriendly:
                case ActionQueueType.CreateItem:
                case ActionQueueType.ReplaceCellItem:
                case ActionQueueType.Pick:
                    lstItemsSelected.Visibility = Visibility.Visible;
                    btnSelectItems.Visibility = Visibility.Visible;
                    break;

                // These have no definable value!
                case ActionQueueType.MoveTerrain:
                case ActionQueueType.Unlock:
                case ActionQueueType.DestroyCellItem:
                case ActionQueueType.DestroyItem:
                case ActionQueueType.DestroyFriendly:
                    break;
                default:
                    txtActionQueueValue.Visibility = Visibility.Visible;
                    break;
            }

            // And finally, setup the lists!
            switch (item.Type)
            {
                case ActionQueueType.ChangeTerrain:
                    _maxQueueItemSelections = 1;
                    _queuedActionItemSource = new ObservableCollection<object>(new List<object> {item.Terrain});
                    _allItemsSource = ModFiles.Terrain;
                    break;
                case ActionQueueType.CreateFriendly:
                    _maxQueueItemSelections = 1;
                    _queuedActionItemSource= item.LivingEntities;
                    _allItemsSource = ModFiles.LivingEntities;
                    break;
                case ActionQueueType.CreateItem:
                case ActionQueueType.ReplaceCellItem:
                    // Limit to 1!!!
                    _queuedActionItemSource = item.Items;
                    _maxQueueItemSelections = 1;
                    _allItemsSource = ModFiles.Items;
                    break;
                case ActionQueueType.Move:
                case ActionQueueType.Pick:
                    // More than 1 item allowed here.
                    _queuedActionItemSource = item.Items;
                    _allItemsSource = ModFiles.Items;
                    break;
                case ActionQueueType.PickFriendly:
                    _queuedActionItemSource = item.LivingEntities;
                    _allItemsSource = ModFiles.LivingEntities;
                    break;
            }
            lstItemsSelected.ItemsSource = _queuedActionItemSource;


            gbQueuedAction.Visibility = lstItemsSelected.Visibility != Visibility.Collapsed ||
                                        btnSelectItems.Visibility != Visibility.Collapsed ||
                                        chkUseSource.Visibility != Visibility.Collapsed ||
                                        txtActionQueueValue.Visibility != Visibility.Collapsed
                                            ? Visibility.Visible
                                            : Visibility.Collapsed;
        }

        private void btnSelectItems_Click(object sender, RoutedEventArgs e)
        {
            var wnd = new SelectFromCollectionWindow(_allItemsSource, _queuedActionItemSource as IEnumerable<object>, _maxQueueItemSelections);
            wnd.ShowDialog();
            _queuedActionItemSource = wnd.GetSelectedItems().ToList();
            lstItemsSelected.ItemsSource = _queuedActionItemSource;
            var item = gbQueuedAction.DataContext as ActionQueueItem;

            switch (item.Type)
            {
                case ActionQueueType.ChangeTerrain:
                    item.Terrain = (_queuedActionItemSource).FirstOrDefault() as Terrain;
                    break;
                case ActionQueueType.CreateItem:
                case ActionQueueType.ReplaceCellItem:
                case ActionQueueType.Move:
                case ActionQueueType.Pick:
                    item.Items = new ObservableCollection<Item>(_queuedActionItemSource.Cast<Item>());
                    break;
                case ActionQueueType.PickFriendly:
                case ActionQueueType.CreateFriendly:
                    item.LivingEntities = new ObservableCollection<LivingEntity>(_queuedActionItemSource.Cast<LivingEntity>());
                    break;
            }
        }
    }
}
